package com.franklin.java.utils;

import com.flychord.jdk.util.tuple.Tuple2;
import com.flychord.jdk.util.tuple.TupleAble;
import com.franklin.plugins.common.utils.DataCheckUtils;
import com.franklin.plugins.common.utils.StringHelper;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiFile;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.xml.XmlFile;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.xml.DomElement;
import com.intellij.util.xml.DomFileElement;
import com.intellij.util.xml.DomService;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

import static com.flychord.jdk.util.tuple.TupleAble.tuple;

public final class DomUtils {

    private DomUtils() {
        throw new UnsupportedOperationException();
    }

    @NotNull
    @NonNls
    public static <T extends DomElement> List<T> findDomElements(@NotNull Project project, Class<T> clazz,String path) {
        GlobalSearchScope scope = GlobalSearchScope.allScope(project);
        List<DomFileElement<T>> elements = DomService.getInstance().getFileElements(clazz, project, scope);
        if (DataCheckUtils.isEmpty(elements)){
            return Collections.emptyList();
        }
        return elements.stream()
                .map(element -> {
                    String filePath = element.getFile().getVirtualFile().getPath();
                    String samePath = StringHelper.longestCommonSubString(path, filePath);
                    return TupleAble.tuple(samePath.length(),element);
                })
                .sorted(Comparator.comparingInt(Tuple2::_1))
                .map(Tuple2::_2)
                .map(DomFileElement::getRootElement)
                .collect(Collectors.toList());
    }

    /**
     * 是否是xml mapper file
     * @param file
     * @return
     */
    public static boolean isMybatisFile(@Nullable PsiFile file) {
        if (!isXmlFile(file)) {
            return false;
        }
        XmlTag rootTag = ((XmlFile) file).getRootTag();
        return null != rootTag && rootTag.getName().equals("mapper");
    }

    public static boolean isMybatisConfigurationFile(@NotNull PsiFile file) {
        if (!isXmlFile(file)) {
            return false;
        }
        XmlTag rootTag = ((XmlFile) file).getRootTag();
        return null != rootTag && rootTag.getName().equals("configuration");
    }

    public static boolean isBeansFile(@NotNull PsiFile file) {
        if (!isXmlFile(file)) {
            return false;
        }
        XmlTag rootTag = ((XmlFile) file).getRootTag();
        return null != rootTag && rootTag.getName().equals("beans");
    }

    static boolean isXmlFile(@NotNull PsiFile file) {
        return file instanceof XmlFile;
    }

}